const { Client } = require('ssh2');
const CryptoUtil = require('../utils/crypto');

class SSHService {
  async testConnection(serverConfig) {
    return new Promise((resolve, reject) => {
      const conn = new Client();

      conn.on('ready', () => {
        console.log('SSH连接成功');
        // 测试执行简单命令
        conn.exec('echo "Connection successful"', (err, stream) => {
          if (err) {
            console.error('执行命令失败:', err);
            conn.end();
            return reject(err);
          }

          stream.on('close', () => {
            conn.end();
            resolve({ success: true, message: '连接测试成功' });
          }).on('data', (data) => {
            console.log('测试输出:', data.toString());
          });
        });
      });

      conn.on('error', (err) => {
        console.error('SSH连接错误:', err);
        reject({ success: false, message: `连接失败: ${err.message}` });
      });

      conn.on('keyboard-interactive', (name, instructions, lang, prompts, finish) => {
        console.log('需要交互式认证');
        finish([serverConfig.password]);
      });

      // 解密私钥（如果是加密的）
      let privateKey = serverConfig.privateKey;
      if (serverConfig.isEncrypted) {
        try {
          privateKey = CryptoUtil.decrypt(serverConfig.privateKey);
        } catch (error) {
          console.error('密钥解密失败:', error);
          return reject({ success: false, message: '密钥解密失败' });
        }
      }

      try {
        const connectConfig = {
          host: serverConfig.host,
          port: serverConfig.port || 22,
          username: serverConfig.username,
          tryKeyboard: true,
          debug: console.log // 添加调试输出
        };

        // 如果提供了密码，使用密码认证
        if (serverConfig.password) {
          connectConfig.password = serverConfig.password;
        }

        // 如果提供了私钥，使用私钥认证
        if (privateKey) {
          connectConfig.privateKey = privateKey;
          if (serverConfig.passphrase) {
            connectConfig.passphrase = serverConfig.passphrase;
          }
        }

        console.log('尝试SSH连接:', {
          host: connectConfig.host,
          port: connectConfig.port,
          username: connectConfig.username,
          hasPassword: !!connectConfig.password,
          hasPrivateKey: !!connectConfig.privateKey
        });

        conn.connect(connectConfig);
      } catch (error) {
        console.error('SSH连接配置错误:', error);
        reject({ success: false, message: `连接配置错误: ${error.message}` });
      }
    });
  }

  async getServerStatus(serverConfig) {
    return new Promise((resolve, reject) => {
      const conn = new Client();

      conn.on('ready', () => {
        // 获取CPU、内存和磁盘使用情况的命令
        const commands = [
          "top -bn1 | grep 'Cpu(s)' | awk '{print $2}'", // CPU使用率
          "free | grep Mem | awk '{print $3/$2 * 100.0}'", // 内存使用率
          "df -h / | tail -1 | awk '{print $5}' | cut -d'%' -f1" // 磁盘使用率
        ];

        let results = {
          cpu: 0,
          memory: 0,
          disk: 0
        };

        let completed = 0;

        commands.forEach((cmd, index) => {
          conn.exec(cmd, (err, stream) => {
            if (err) {
              conn.end();
              return reject(err);
            }

            let data = '';
            stream.on('data', (chunk) => {
              data += chunk;
            });

            stream.on('close', () => {
              const value = parseFloat(data.trim());
              switch (index) {
                case 0:
                  results.cpu = Math.round(value);
                  break;
                case 1:
                  results.memory = Math.round(value);
                  break;
                case 2:
                  results.disk = Math.round(value);
                  break;
              }

              completed++;
              if (completed === commands.length) {
                conn.end();
                resolve(results);
              }
            });
          });
        });
      });

      conn.on('error', (err) => {
        reject(err);
      });

      // 连接配置
      const connectConfig = {
        host: serverConfig.host,
        port: serverConfig.port || 22,
        username: serverConfig.username,
        tryKeyboard: true
      };

      if (serverConfig.authType === 'password') {
        connectConfig.password = serverConfig.password;
      } else {
        connectConfig.privateKey = serverConfig.privateKey;
        if (serverConfig.passphrase) {
          connectConfig.passphrase = serverConfig.passphrase;
        }
      }

      conn.connect(connectConfig);
    });
  }
}

module.exports = new SSHService(); 